﻿using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Data;
using com.dz.common;
using com.dz.entity;
namespace com.dz.components.background
{
    public class ShouDa8CatchManager
    {
        DataManager m_data_mgr = new DataManager();
        FileManager m_file_mgr = new FileManager();

        const  string c_domain = "http://www.shouda8.com";
        //搜索地址
        const string c_search_url = "http://www.shouda8.com/Ebook/Index.aspx?searchkey={0}&searchclass=1";

        /// <summary>
        /// 章节列表页面
        /// </summary>
        const string c_chapter_url = "http://www.shouda8.com/shouda/{0}/index.htm";

        //搜索列表正则
        const string c_search_reg = "<li>.*?<H3><A.*?>(.*?)</A></H3>.*?<div[^<>]*?class=[\'\"]?button[\'\"]?>.*?<a[^<>]*?hrefs*=s*[\'\"s]?[^\"]*\\/(\\d+)[^\"]*[\'\"]?[^<>]*?>(.*?)</a>";
        //匹配分卷正则
        const string c_volume_reg = "<div[^<>]*?class=[\'\"]?chapter_list_chapter_title[\'\"]?>.*?<b>(.*?)</b>.*?</div>";
        //整洁正则
        const string c_chapter_reg = "<div[^<>]*?class=[\'\"]?chapter_list_chapter[\'\"]?><a[^<>]*?title=[\'\"]?更新时间:(\\d{4}-[\\d{2}|\\d{1}]+-[\\d{2}|\\d{1}]+\\s[\\d{2}|\\d{1}]+:[\\d{2}|\\d{1}]+:[\\d{2}|\\d{1}]+).*?更新字数:(\\d{1,})[\'\"]?[^<>]*?href=[\'\"](\\d+)\\.htm[\'\"]?>(.*?)</a></div>";
        //更新时间
        const int c_update_time_index = 1;
        //更新字数
        const int c_update_time_chaptetr_size_index = 2;
        //章节id
        const int c_chapter_id_index = 3;
        //章节名称
        const int c_chapter_name_index = 4;
        //站点编码
        Encoding c_site_encoding = Encoding.GetEncoding("gb2312");
        //书名在正则中的索引
        const int c_book_name_index = 1;
        //章节列表url在正则中的索引
        const int c_book_id_index = 2;
        //章节列表导航在正则中的索引
        const int c_menu_index = 3;
        const string c_menu_txt = "在线阅读";

        /// <summary>
        /// 章节内容地址
        /// </summary>
        const string c_chapter_content_url = "http://www.shouda8.com/shouda/{0}/{1}.htm";
        const string c_chapter_content_reg = "<div[^<>]*?id=[\'\"]?text_area[\'\"]?>(.*?)</div>";

   

        public void StartCatchASC()
        {
            int t_total_count=0;
            DataSet t_ds_asc = m_data_mgr.GetSiteCatchBookList(AppConfig.CatchBookChapterMode, (int)Consts.Site.shouda8, (int)Consts.OrderType.ASC, 1, AppConfig.PageSize, (int)Consts.PageType.OutTotalCount, out t_total_count);
            int t_page_count = t_total_count % AppConfig.PageSize == 0 ? t_total_count / AppConfig.PageSize : (t_total_count / AppConfig.PageSize + 1);

             if (t_ds_asc == null || t_ds_asc.Tables.Count <= 0 || t_ds_asc.Tables[0].Rows.Count <= 0)
                return;
             StartCatchBookList(t_ds_asc, Consts.OrderType.ASC);

             for (int index = 2; index < t_page_count; index++)
             {
                 t_ds_asc = m_data_mgr.GetSiteCatchBookList(AppConfig.CatchBookChapterMode, (int)Consts.Site.shouda8, (int)Consts.OrderType.ASC, 1, AppConfig.PageSize, (int)Consts.PageType.OutTotalCount, out t_total_count);
                 StartCatchBookList(t_ds_asc, Consts.OrderType.ASC);
             }

           
        }

        public void StartCatchDESC()
        {
            int t_total_count = 0;
            DataSet t_ds_desc = m_data_mgr.GetSiteCatchBookList(AppConfig.CatchBookChapterMode, (int)Consts.Site.shouda8, (int)Consts.OrderType.DESC, 1, AppConfig.PageSize, (int)Consts.PageType.OutTotalCount, out t_total_count);
            int t_page_count = t_total_count % AppConfig.PageSize == 0 ? t_total_count / AppConfig.PageSize : (t_total_count / AppConfig.PageSize + 1);

            if (t_ds_desc == null || t_ds_desc.Tables.Count <= 0 || t_ds_desc.Tables[0].Rows.Count <= 0)
                return;
            StartCatchBookList(t_ds_desc,Consts.OrderType.DESC);

            for (int index = 2; index < t_page_count; index++)
            {
                t_ds_desc = m_data_mgr.GetSiteCatchBookList(AppConfig.CatchBookChapterMode, (int)Consts.Site.shouda8, (int)Consts.OrderType.ASC, 1, AppConfig.PageSize, (int)Consts.PageType.OutTotalCount, out t_total_count);
                StartCatchBookList(t_ds_desc, Consts.OrderType.DESC);
            }

        }

        private void StartCatchBookList(DataSet i_ds,Consts.OrderType i_order_type)
        {
            long t_book_id = 0;
            long t_site_book_id = 0;
            for (int index = 0; index < i_ds.Tables[0].Rows.Count; index++)
            {
                if (!long.TryParse(i_ds.Tables[0].Rows[index]["bookId"].ToString(), out t_book_id))
                    t_book_id = 0;
                if (!long.TryParse(i_ds.Tables[0].Rows[index]["oldbookid"].ToString(), out t_site_book_id))
                    t_site_book_id = 0;
                if (i_ds.Tables[0].Rows[index]["comfrom"].ToString().ToLower().IndexOf("shouda") > -1)
                {
                    CatchChapter(i_ds.Tables[0].Rows[index]["comfrom"].ToString(), t_book_id,t_site_book_id,i_order_type);
                }
                else
                {
                    StartCatchBook(i_ds.Tables[0].Rows[index]["bookName"].ToString(), t_book_id, i_order_type);
                }
            }
        }

        public void StartCatchBook(string i_book_name, long i_book_id,Consts.OrderType i_order_type)
        {
 
            string t_soso_url = string.Empty;
            string t_html = string.Empty;
            MatchCollection t_ma = null;
            long t_site_book_id = 0;
   
            try
            {
 
                t_soso_url = string.Format(c_search_url, HttpUtility.UrlEncode(i_book_name, c_site_encoding));

                t_html = BookSiteManager.ReadUrl(t_soso_url, c_site_encoding);

                if (!string.IsNullOrEmpty(t_html))
                {
                    t_ma = Regex.Matches(t_html, c_search_reg, RegexOptions.IgnoreCase | RegexOptions.Compiled);

                    if (t_ma != null && t_ma.Count > 0)
                    {
                        foreach (Match t_mc in t_ma)
                        {
                            if (t_mc.Groups.Count >= c_menu_index)
                            {
                                if (t_mc.Groups[c_menu_index].Value.ToString().Equals(c_menu_txt) && t_mc.Groups[c_book_name_index].Value.ToString().Equals(string.Format("《{0}》", i_book_name)))
                                {
                                    if (!long.TryParse(t_mc.Groups[c_book_id_index].Value.ToString(), out t_site_book_id))
                                        t_site_book_id = 0;
                                    if (t_site_book_id <= 0)
                                        continue;
                                    CatchChapter(string.Format(c_chapter_url, t_site_book_id), i_book_id, t_site_book_id,i_order_type);
                                }
                            }
                        }
                    }
                }
                else
                {
                    LogHelper.Debug(string.Format("搜索:{0},url={1},没数据", i_book_name, t_soso_url));
                }
          
            }
            catch (Exception ex)
            {
                LogHelper.Error("搜索书籍失败" + ex.ToString());
            }
            
        }

        /// <summary>
        /// 抓取章节列表页面
        /// </summary>
        /// <param name="i_chapter_url"></param>
        /// <param name="i_book_id"></param>
        private void CatchChapter(string i_soso_url, long i_book_id, long i_site_book_id,Consts.OrderType i_order_type)
        {
            string t_soso_url = i_soso_url;
            string t_html = string.Empty;
            MatchCollection t_ma = null;
            string t_volume_name = string.Empty;
            string t_sub_html = string.Empty;
            try
            {
                t_html = BookSiteManager.ReadUrl(t_soso_url, c_site_encoding);
                t_ma = Regex.Matches(t_html, c_volume_reg, RegexOptions.IgnoreCase | RegexOptions.Compiled);
                if (t_ma != null && t_ma.Count > 0)
                {
                    for (int t_index = 0; t_index < t_ma.Count - 1; t_index++)
                    {
                        t_volume_name = t_ma[t_index].Groups[1].Value.ToString();
                        t_sub_html = t_html.Substring(t_ma[t_index].Groups[1].Index, t_ma[t_index + 1].Groups[1].Index - t_ma[t_index].Groups[1].Index);
         
                        ParseContent(i_site_book_id, i_book_id, t_volume_name, t_sub_html,i_order_type,i_soso_url);
                    }

                    t_volume_name = t_ma[t_ma.Count - 1].Groups[1].Value.ToString();
                    t_sub_html = t_html.Substring(t_ma[t_ma.Count - 1].Index);

                    ParseContent(i_site_book_id, i_book_id, t_volume_name, t_sub_html,i_order_type,i_soso_url);
                   
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("获取章节列表失败" + ex.ToString());
            }

        }

        /// <summary>
        /// 解析章节
        /// </summary>
        /// <param name="i_site_book_id"></param>
        /// <param name="i_book_id"></param>
        /// <param name="i_volume_name"></param>
        /// <param name="t_html"></param>
        private void ParseContent(long i_site_book_id,long i_book_id, string i_volume_name,string i_html,Consts.OrderType i_order_type,string i_book_chapter_url)
        {
            if (string.IsNullOrEmpty(i_html))
                return;

            if (string.IsNullOrEmpty(i_volume_name))
            {
                i_volume_name = "残卷";
            }
            MatchCollection t_ma = Regex.Matches(i_html, c_chapter_reg, RegexOptions.IgnoreCase | RegexOptions.Compiled);
            DateTime t_update_time = DateTime.Now;
            int t_update_chapter_size = 0;
            string t_site_chapter_id = string.Empty;
            string t_chapter_name = string.Empty;
            bool t_is_vip = false;
            long t_chapter_id = 0;
            if (!string.IsNullOrEmpty(i_volume_name) && i_volume_name.ToLower().IndexOf("vip") > -1)
            {
                t_is_vip = true;
            }
            if (t_ma != null)
            {
              
                foreach (Match t_mc in t_ma)
                {
                    if (t_mc.Groups.Count >= c_chapter_name_index)
                    {
                        if (!DateTime.TryParse(t_mc.Groups[c_update_time_index].Value.ToString(), out t_update_time))
                            t_update_time = DateTime.Now;
                        if (!int.TryParse(t_mc.Groups[c_update_time_chaptetr_size_index].Value.ToString(), out t_update_chapter_size))
                            t_update_chapter_size = 0;
                        t_site_chapter_id = t_mc.Groups[c_chapter_id_index].Value.ToString();
                        t_chapter_name = t_mc.Groups[c_chapter_name_index].Value.ToString();

                       t_chapter_id= m_data_mgr.InsertBranckBookChapter(i_volume_name, t_chapter_name, t_update_time, t_is_vip,t_update_chapter_size,i_book_id,(int)Consts.Site.shouda8,i_site_book_id,i_book_chapter_url,(int)i_order_type);

                        //章节不存在，取章节内容
                       if (t_chapter_id>0 && m_file_mgr.CheckChaperExist(i_book_id, t_chapter_id) == false)
                       {
                           CatchChapterContent(i_book_id, t_chapter_id, i_site_book_id, t_site_chapter_id);
                       }
                      
                    }
                }
            }
        }

        /// <summary>
        /// 抓取章节内容
        /// </summary>
        /// <param name="i_book_id"></param>
        /// <param name="i_chapter_id"></param>
        /// <param name="i_site_book_id"></param>
        /// <param name="i_site_chapter_id"></param>
        private void CatchChapterContent(long i_book_id, long i_chapter_id, long i_site_book_id, string i_site_chapter_id)
        {
            string t_soso_url = string.Format(c_chapter_content_url, i_site_book_id, i_site_chapter_id);

            try
            {
                string t_html = BookSiteManager.ReadUrl(t_soso_url, c_site_encoding);
                if (!string.IsNullOrEmpty(t_html))
                {
                    Match t_mc = Regex.Match(t_html, c_chapter_content_reg, RegexOptions.IgnoreCase | RegexOptions.Compiled);
                    if (t_mc != null && t_mc.Groups.Count > 0)
                    {
                        string t_chapter_content = t_mc.Groups[1].Value.ToString();
                        //100字以上才算章节
                        if (!string.IsNullOrEmpty(t_chapter_content) && t_chapter_content.Length>100)
                        {
                            t_chapter_content = ReplaceContent(t_chapter_content);
                            t_chapter_content = string.Format("document.write('{0}');", t_chapter_content);
                            m_file_mgr.WriteBookContent(i_book_id, i_chapter_id, t_chapter_content);
                        }
                       
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("获取章节内容失败" + ex.ToString());
            }
        }

        private string ReplaceContent(string i_text)
        {
            if (string.IsNullOrEmpty(i_text))
                return string.Empty;
            i_text = i_text.Replace("<a href=http://www.qidian.com>起点中文网 www.qidian.com 欢迎广大书友光临阅读，最新、最快、最火的连载作品尽在起点原创！</a>", "");
            i_text=i_text.Replace("ahref=http://www.&gt;起点中文网www.欢迎广大书友光临阅读，最新、最快、最火的连载作品尽在起点原创！","");
            i_text = Regex.Replace(i_text, "<a.*?>.*?</a>", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_text = Regex.Replace(i_text, "<script.*?>.*?</script>", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_text = Regex.Replace(i_text, "<font.*?>.*?</font>", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_text = Regex.Replace(i_text, "<div.*?>.*?</div>", "", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            return i_text;
        }
    }
}
